import {
  init,
  classModule,
  propsModule,
  styleModule,
  eventListenersModule,
  h,
} from 'snabbdom'

const patch = init([
  classModule,
  propsModule,
  styleModule,
  eventListenersModule,
])

let vnode
const margin = 8
let sortBy = 'score'
let totalHeight = 0
const originalData = [
  { name: 'rashford', sex: 2, score: 100, elmHeight: 0 },
  { name: 'rooney', sex: 2, score: 97, elmHeight: 0 },
  { name: 'ronaldo', sex: 2, score: 103, elmHeight: 0 },
  { name: 'messi', sex: 2, score: 101, elmHeight: 0 },
  { name: 'pirlo', sex: 2, score: 90, elmHeight: 0 },
  { name: 'sun', sex: 1, score: 85, elmHeight: 0 },
  { name: 'geele', sex: 1, score: 83, elmHeight: 0 },
  { name: 'tracy', sex: 1, score: 55, elmHeight: 0 },
  { name: 'marry', sex: 1, score: 68, elmHeight: 0 },
  { name: 'malone', sex: 2, score: 65, elmHeight: 0 },
]
let data = [
  { name: 'alice', sex: 1, score: 100, elmHeight: 0 },
  { name: 'tom', sex: 2, score: 99, elmHeight: 0 },
  { name: 'jim', sex: 2, score: 95, elmHeight: 0 },
  { name: 'mike', sex: 2, score: 90, elmHeight: 0 },
  { name: 'david', sex: 2, score: 88, elmHeight: 0 },
  { name: 'lucy', sex: 1, score: 85, elmHeight: 0 },
  { name: 'lily', sex: 1, score: 80, elmHeight: 0 },
  { name: 'luis', sex: 1, score: 75, elmHeight: 0 },
  { name: 'jack', sex: 2, score: 70, elmHeight: 0 },
  { name: 'joe', sex: 2, score: 65, elmHeight: 0 },
]

const render = () => {
  data = data.reduce((acc, m) => {
    const last = acc[acc.length - 1]
    m.offset = last ? last.offset + last.elmHeight + margin : margin
    return acc.concat(m)
  }, []);
  totalHeight =
    data.length === 0
      ? 0
      : data[data.length - 1].offset + data[data.length - 1].elmHeight
  vnode = patch(vnode, view(data))
}

const changeSort = prop => {
  sortBy = prop
  data.sort((a, b) => {
    if (a[prop] > b[prop]) {
      return prop !== 'score' ? 1 : -1
    }
    if (a[prop] < b[prop]) {
      return prop !== 'score' ? -1 : 1
    }
    return 0
  });
  render()
}

const add = () => {
  const n = originalData[Math.floor(Math.random() * 10)]
  for (let i = 0, len = data.length; i < len; i++) {
    if (data[i].name === n.name) {
      alert(`此同学${n.name}已在列表中`)
      return false
    }
  }
  data = [
    { name: n.name, sex: n.sex, score: n.score, elmHeight: 0 },
  ].concat(data);
  render();
  render();
}

const remove = item => {
  data = data.filter(s => {
    return s !== item;
  });
  render();
}

const listView = item => {
  return h('div.row', 
    {
      key: item.name,
      style: {
        opacity: '0',
        transform: 'translate(-200px)',
        delayed: { transform: `translateY(${item.offset}px)`, opacity: '1' },
        remove: {
          opacity: '0',
          transform: `translateY(${item.offset}px) translateX(200px)`,
        },
      },
      hook: {
        insert: vnode => {
          item.elmHeight = vnode.elm.offsetHeight;
        },
      },
    },
    [
      h('div', {
        style: { fontWeight: 'bold' },
      }, item.name),
      h('div', {
        style: {
          textAlign: 'center',
        },
      }, item.sex === 1 ? '女' : '男'),
      h('div', item.score),
      h(
        'div.btn.rm-btn',
        {
          on: {
            click: () => {
              remove(item);
            },
          },
        },
        'x'
      ),
    ]
  )
}

const view = data => {
  return h('div', [
    h('h1', '学生排行'),
    h('div', [
      h('a.btn.add', { on: { click: add } }, '添加'),
      '排序方式：',
      h('span.btn-group', [
        h('a.btn', {
          class: {
            active: sortBy === 'score',
          },
          on: {
            click: () => {
              changeSort('score')
            },
          },
        }, '按成绩排序'),
        h('a.btn', {
          class: {
            active: sortBy === 'name',
          },
          on: {
            click: () => {
              changeSort('name')
            },
          },
        }, '按名称排序'),
        h('a.btn', {
          class: {
            active: sortBy === 'sex',
          },
          on: {
            click: () => {
              changeSort('sex')
            },
          },
        }, '按性别排序'),
      ])
    ]),
    h('div.list', {
      style: {
        height: `${totalHeight}px`,
      },
    }, data.map(listView))
  ])
}

window.addEventListener('DOMContentLoaded', () => {
  const app = document.getElementById('app')
  vnode = patch(app, view(data))
  render()
})
